/**
 * @file tuya_main.c
 * @brief 涂鸦应用入口文件，原厂main()->user_main()->pre_app_init()->tuya_iot_init()->app_init()->
 *        pre_deivce_init()->device_init()
 *        
 *        对于每一个芯片平台，存在一些差异性，此处可以对差异性进行处理，应用的特殊处理，应该放到应用预留接口里实现。应用
 *        预留接口包括：
 *        pre_app_init(): 用于系统初始的前置准备工作，此时涂鸦Device OS尚未启动
 *        app_init(): 用于应用初始化，此时涂鸦Device OS已经初始化
 *        pre_device_init()： 设备功能启动前置准备工作，此时设备功能尚未启动
 *        device_init()： 设备功能启动，完成之后设备进入正常工作状态
 *        
 * @warning 此文件如非必要，禁止修改。
 *        
 * @copyright Copyright (c) {2018-2020} 涂鸦科技 www.tuya.com
 * 
 */
#include "tal_thread.h"
#include "tuya_thread_priority.h"
#include "tuya_cloud_types.h"
#include "tuya_nbiot_main.h"
#include "tuya_mf_test.h"
#include "tuya_user_api.h"

/**
 * @brief 应用初始化前置准备工作
 *      
 * 
 * @return int 
 * 
 * @note 在此函数中，应用可以执行一些配置设置、事件关注等和具体功能操作无关的工作，应用必须对其进行实现，如果不需要，则实现空函数。
 */
extern int pre_init(void);

/**
 * @brief tuya_user_prod_test 是成品产测回调接口
 * 
 * @return OPERATE_RET 
 * 
 * @note 应用必须对其进行实现，如果不需要，则实现空函数
 * 
 */
extern OPERATE_RET tuya_user_prod_test(USHORT_T cmd, UCHAR_T *data, UINT_T len, OUT UCHAR_T *ret_data, OUT USHORT_T *ret_len);
/**
 * @brief 应用初始化接口
 * 
 * @return int 
 * 
 * @note 应用必须对其进行实现，如果不需要，则实现空函数
 * 
 */
extern int device_init(void);

static THREAD_HANDLE app_init_task = NULL;

void user_main(void)
{
    OPERATE_RET op_ret = OPRT_OK;

    //涂鸦Device OS   日志及kv初始化:不要修改
    tuya_nbiot_init_params();

    // 应用初始化前置准备工作，用户在此处可以进行一些设置，为后续继续标准化预留
    pre_init();

    //涂鸦Device OS SDK 初始化前准备:不要修改
    #ifdef TUYA_RELEASE
    __tuya_nbiot_pre_init(APP_BIN_NAME, USER_SW_VER, true);
    #else
    __tuya_nbiot_pre_init(APP_BIN_NAME, USER_SW_VER, false);
    #endif

    // 产测初始化， 注册函数需要应用实现，其中串口驱动不需要应用提供
    MF_IMPORT_INTF_S user_intf = {
        .user_test = tuya_user_prod_test,
    };
    mf_test_system_start(&user_intf,APP_BIN_NAME, USER_SW_VER);

    //涂鸦Device OS SDK 初始化:不要修改
    __tuya_nbiot_init();

    //应用初始化
    device_init();

    //标记涂鸦应用初始化完成:不要修改
    tuya_nbiot_set_initialized();
}

static void app_init_thread(void* param)
{
    user_main();
    /* Kill init thread after all init tasks done */
    tal_thread_delete(app_init_task);
    app_init_task = NULL;
}

void tuya_app_main(void)
{
	THREAD_CFG_T cfg = {
		.priority = TASK_PRIO_NORMAL,
		.stackDepth = 4096*2,
		.thrdname = "app_init_thread",
	};
	tal_thread_create_and_start(&app_init_task, NULL, NULL, app_init_thread, NULL, &cfg);
}

